#include "spdlog/spdlog.h"
#include "spdlog/cfg/env.h"
#include "spdlog/cfg/argv.h"
#include "spdlog/sinks/stdout_color_sinks.h"
#include "spdlog/sinks/basic_file_sink.h"

#include "AEyeSDKConfig.hpp"
#include "ecast.h"

namespace aeye {

// will expand public api later - for now, just need a way for customers to init the logger in their applications
// they need to call InitializeLogger at their main because this lib doesn't provide a single entry point for us
// to configure it in
/*
enum class LogLevel {
  trace = 0,
  debug = 1,
  info = 2,
  warn = 3,
  err = 4,
  critical = 5,
  off = 6,
};
 */

static std::atomic<bool> is_logger_init {false};

void InitializeLogger(const std::string& log_file) {
  if (is_logger_init) {
    spdlog::warn("Logger already initialized - not doing it again.");
    return;
  }
  auto stderr_sink = std::make_shared<spdlog::sinks::stderr_color_sink_mt>();
  stderr_sink->set_level(spdlog::level::info);

  auto file_sink = std::make_shared<spdlog::sinks::basic_file_sink_mt>(log_file);
  file_sink->set_level(spdlog::level::trace);

  auto list = spdlog::sinks_init_list({stderr_sink, file_sink});
  spdlog::set_default_logger(std::make_shared<spdlog::logger>("aeyesdk", list));
  spdlog::set_pattern("[%Y-%m-%d %T.%e] [%l] [%t] %v");
  spdlog::set_level(spdlog::level::trace);

  spdlog::info("Initialized logger.");
  is_logger_init.store(true);

}

void InitializeLoggerStderrOnly() {
  if (is_logger_init) {
    spdlog::warn("Logger already initialized - not doing it again.");
    return;
  }
  auto stderr_sink = std::make_shared<spdlog::sinks::stderr_color_sink_mt>();
  stderr_sink->set_level(spdlog::level::trace);

  spdlog::set_default_logger(std::make_shared<spdlog::logger>("aeyesdk", stderr_sink));
  spdlog::set_pattern("[%Y-%m-%d %T.%e] [%l] [%t] %v");
  spdlog::set_level(spdlog::level::trace);

  spdlog::info("Initialized logger.");
  is_logger_init.store(true);

}

void InitializeLoggerFileOnly(const std::string &log_file) {
  if (is_logger_init) {
    spdlog::warn("Logger already initialized - not doing it again.");
    return;
  }
  auto file_sink = std::make_shared<spdlog::sinks::basic_file_sink_mt>(log_file);
  file_sink->set_level(spdlog::level::trace);

  spdlog::set_default_logger(std::make_shared<spdlog::logger>("aeyesdk", file_sink));
  spdlog::set_pattern("[%Y-%m-%d %T.%e] [%l] [%t] %v");
  spdlog::set_level(spdlog::level::trace);

  spdlog::info("Initialized logger.");
  is_logger_init.store(true);
}

void InitializeLoggerToVoid() {
  if (is_logger_init) {
    spdlog::warn("Logger already initialized - not doing it again.");
    return;
  }
  std::shared_ptr<spdlog::sinks::basic_file_sink_mt> file_sink;
#ifndef _MSC_VER
  file_sink = std::make_shared<spdlog::sinks::basic_file_sink_mt>("/dev/null");
#else
  file_sink = std::make_shared<spdlog::sinks::basic_file_sink_mt>("NUL");
#endif
  spdlog::set_default_logger(std::make_shared<spdlog::logger>("aeyesdk", file_sink));
  is_logger_init.store(true);


}
}